<?php

class DBConnException extends Exception
{
    public function __construct($alert,$query)
    {
        parent::__construct("<p><b>DBConnException:</b> An error $alert occurred when executing $query.</p>");
    }
}
 
abstract class DBConnection
{
    private static $_getConn = NULL;
     
    private $_db_user,
            $_db_pass,
            $_db_name,
            $_db_host;
             
    public $RowCount,
           $LastInsertID,
           $AffectedRows;
      
    
    public function __construct($dbUser,$dbPass,$dbName,$dbHost)
    {
        $this->_db_user = trim($dbUser);
        $this->_db_pass = trim($dbPass);
        $this->_db_name = trim($dbName);
        $this->_db_host = trim($dbHost);
    }
     
    public function __destruct()
    {
        $this->disconnect();
    }
     
    public function connect()
    {
        if(self::$_getConn===NULL)
        {
            $conn = @new mysqli($this->_db_host,$this->_db_user,$this->_db_pass,$this->_db_name);
            if(mysqli_connect_errno() !== 0) throw new DBConnException(mysqli_connect_error(),"Connect Database");
            $conn->query("SET NAMES 'utf8'");
                 
            self::$_getConn = $conn;
        }  
        return self::$_getConn;
    }
     
    public function clearText($string = '')
    {
        $conn = self::connect();
        if($conn!==NULL)
        {
            $string = $conn->real_escape_string($string);
            return $string;
        }
    }
     
    public function query($sql)
    {
        $sql = trim($sql);
        $sql_arr = explode(' ',$sql);
         
        $conn = self::connect();
        $result = $conn->query($sql);
        if($conn->errno !== 0) throw new DBConnException($conn->error,$sql);
         
        switch ($sql_arr[0])
        {
            case "SELECT":
                $rows = array();
                while( ($row = $result->fetch_assoc())!= NULL )
                {
                    $rows[] = $row;
                }
                $this->RowCount = $result->num_rows;
                return $rows;
            break;
            case "INSERT":
                $this->LastInsertID = $conn->insert_id;
            break;
            case "UPDATE":
            case "DELETE":
                $this->AffectedRows = $conn->affected_rows;
            break;
        }
    }
     
    public function disconnect()
    {
        $conn = self::connect();
        mysqli_close($conn);
    }
}
class ActiveRecord extends DBConnection
{
    public $table='',
           $condition='',
           $limit='',
           $order='';
     
    public function select($rows='*')
    {
        if($this->table==='') throw new DBConnException("table name is empty","select method");
             
        $query = "SELECT ".trim($rows)." FROM ".trim($this->table);
        if(trim($this->condition)!=='') $query.= " WHERE ".trim($this->condition);
        if(trim($this->order)!=='') $query.= " ORDER BY ".trim($this->order);
        if(trim($this->limit)!=='') $query.= " LIMIT ".trim($this->limit);
         
        $result = $this->query($query);
        if($result!=='' or $result!==NULL) return $result;
    }
     
    public function insert($data)
    {
        if($this->table==='') throw new DBConnException("table name is empty","select method");
        if(!is_array($data) or empty($data)) throw new DBConnException("data must be an array, and it can not be empty","insert method");
         
        $rows = '';
        $values = '';
        $index = 1;
         
        foreach($data as $key => $value)
        {
            if($index == count($data))
            {
                $rows .= $key;
                $values .= "'".$value."'";
                continue;
            }
            $rows .= $key.',';
            $values .= "'".$value."'".',';
            $index++;
        }
         
        $query = "INSERT INTO ".trim($this->table)."($rows) VALUES($values)";
        $this->query($query);
         
    }
     
    public function update($data)
    {
        if($this->table==='') throw new DBConnException("table name is empty","select method");
        if(!is_array($data) or empty($data)) throw new DBConnException("data must be an array, and it can not be empty","update method");
         
        $rows = '';
        $index = 1;
         
        foreach($data as $key => $value)
        {
            if($index == count($data))
            {
                $rows .= $key.'='."'".$value."'";
                continue;
            }
            $rows .= $key.'='."'".$value."'".',';
            $index++;
        }
        if($this->condition!=='')
            $query = "UPDATE ".trim($this->table)." SET $rows WHERE ".trim($this->condition);
        else
            $query = "UPDATE ".trim($this->table)." SET $rows";
        $this->query($query);
    }
     
    public function delete()
    {
        if($this->table==='') throw new DBConnException("table name is empty","select method");
        if($this->condition==='') throw new DBConnException("delete a record without condition","delete method");
         
        $query = "DELETE FROM ".trim($this->table)." WHERE ".trim($this->condition);
        $this->query($query);
    }
}

?>